package com.bilibili.magicasakura.widgets;


import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.ComponentState;
import ohos.agp.components.Switch;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.render.BlendMode;
import ohos.agp.utils.Color;
import ohos.global.resource.NotExistException;

import com.bilibili.magicasakura.utils.TintInfo;
import com.bilibili.magicasakura.utils.TintManager;

import java.io.IOException;


/**
 * @author xyczero617@gmail.com
 * @since 17/5/23
 */

class AppCompatSwitchHelper {
    private String sAttrs;
    private TintManager mTintManager;
    private boolean mSkipNextApply;

    private DrawableCallback mDrawableCallback;

    private TintInfo mTintInfo;
    private int mResId;
    private Color mTintResId;

    AppCompatSwitchHelper(Switch switchCompat, TintManager tintManager,
                          String attrs, DrawableCallback callback) {
        this.sAttrs = attrs;
        this.mTintManager = tintManager;
        this.mDrawableCallback = callback;
    }

    private boolean skipNextApply() {
        if (mSkipNextApply) {
            mSkipNextApply = false;
            return true;
        }
        mSkipNextApply = true;
        return false;
    }

    private void setSkipNextApply(boolean flag) {
        mSkipNextApply = flag;
    }

    @SuppressWarnings("ResourceType")
    public void loadFromAttribute(AttrSet attrs, int defStyleAttr) {
        if (sAttrs.equals("thumb_element")) {
            if (attrs.getAttr("thumbTint").isPresent()) {
                mTintResId = attrs.getAttr("thumbTint").get().getColorValue();
                setSupportDrawableTint(mTintResId);
            } else if (attrs.getAttr("thumb_element").isPresent()) {
                Element element = attrs.getAttr("thumb_element").get().getElement();
                if (element != null) {
                    setDrawable(element);
                }
            }
        } else if (sAttrs.equals("track_element")) {
            if (attrs.getAttr("trackTint").isPresent()) {
                mTintResId = attrs.getAttr("trackTint").get().getColorValue();
                setSupportDrawableTint(mTintResId);
            } else if (attrs.getAttr("track_element").isPresent()) {
                Element element = attrs.getAttr("track_element").get().getElement();
                if (element != null) {
                    setDrawable(element);
                }
            }
        }
    }

    /**
     * External use
     */
    public void setDrawable() {
        if (skipNextApply()) return;

        resetTintResource(0);
        setSkipNextApply(false);
    }

    public void setDrawableId(int resId) {
        if (mResId != resId) {
            resetTintResource(resId);

            if (resId != 0) {
                Element drawable = new ShapeElement();
                setDrawable(drawable);
            }
        }
    }

    public void setDrawableTintList(StateElement origin) {
        if (mTintInfo == null) {
            mTintInfo = new TintInfo();
        }
        mTintInfo.mHasTintColor = true;
        mTintInfo.mTintColor = mTintManager.getColorValue();
        applySupportDrawableTint();
    }

    public void setButtonDrawableTintList(Color resId, BlendMode mode) {
        if (mTintResId != resId) {
            mTintResId = resId;
            if (mTintInfo != null) {
                mTintInfo.mHasTintColor = false;
                mTintInfo.mTintColor = 0;
                mTintInfo.mHasTintMode = false;
                mTintInfo.mTintMode = null;
            }
            setSupportDrawableTintMode(mode);
            setSupportDrawableTint(resId);
        }
    }

    /**
     * Internal use
     *
     * @param drawable drawable
     */
    private void setDrawable(Element drawable) {
        if (skipNextApply()) return;

        mDrawableCallback.setDrawable(drawable);
    }

    private boolean setSupportDrawableTint(Color color) {
        if (color != null) {
            if (mTintInfo == null) {
                mTintInfo = new TintInfo();
            }
            mTintInfo.mHasTintColor = true;
            mTintInfo.mTintColor = mTintManager.getReplaceColorValue(color);
        }
        return applySupportDrawableTint();
    }

    private void setSupportDrawableTintMode(BlendMode mode) {
        if (mode != null) {
            if (mTintInfo == null) {
                mTintInfo = new TintInfo();
            }
            mTintInfo.mHasTintMode = true;
            mTintInfo.mTintMode = mode;
        }
    }

    private boolean applySupportDrawableTint() {
        if (mTintInfo != null && mTintInfo.mHasTintColor) {
            int[] states = {ComponentState.COMPONENT_STATE_CHECKED};
            int[] states1 = {ComponentState.COMPONENT_STATE_EMPTY};
            ShapeElement element = new ShapeElement();
            ShapeElement element1 = new ShapeElement();
            element.setCornerRadius(50);
            element1.setCornerRadius(50);
            if (sAttrs.equals("thumb_element")) {
                element.setShape(ShapeElement.OVAL);
                element.setRgbColor(RgbColor.fromArgbInt(mTintInfo.mTintColor));
                element1.setShape(ShapeElement.OVAL);
                element1.setRgbColor(RgbColor.fromArgbInt(Color.LTGRAY.getValue()));

                StateElement stateElement = new StateElement();
                stateElement.addState(states, element);
                stateElement.addState(states1, element1);
                setDrawable(stateElement);
                return true;
            } else if (sAttrs.equals("track_element")) {
                element.setRgbColor(RgbColor.fromArgbInt(mTintInfo.mTintColor));
                element.setShape(ShapeElement.RECTANGLE);
                element1.setRgbColor(RgbColor.fromArgbInt(Color.GRAY.getValue()));
                element1.setShape(ShapeElement.RECTANGLE);
                StateElement stateElement = new StateElement();
                stateElement.addState(states, element);
                stateElement.addState(states1, element1);
                setDrawable(stateElement);
                return true;
            }
        }
        return false;
    }

    private void resetTintResource(int resId) {
        mResId = resId;
        mTintResId = null;
        if (mTintInfo != null) {
            mTintInfo.mHasTintList = false;
            mTintInfo.mTintList = null;
            mTintInfo.mHasTintMode = false;
            mTintInfo.mTintMode = null;
        }
    }

    public void tint() {
        if (mTintResId == null || !setSupportDrawableTint(mTintResId)) {

        }
    }

    public interface DrawableCallback {

        void setDrawable(Element drawable);

        Element getDrawable();
    }

    public interface SwitchCompatExtensible {

        void setTrackTintList(Color color);

        void setTrackTintList(Color color, BlendMode mode);

        void setThumbTintList(Color color);

        void setThumbTintList(Color color, BlendMode mode);
    }
}
